using ICSharpCode.SharpZipLib.Zip;
using System.IO;
using System.Text;
using UnityEngine;

namespace CGF
{
    public class ZipHelper
    {
        public delegate void ProgressAction(float progress);

        /// <summary>
        /// 解压缩
        /// </summary>
        public static bool Unzip(string zipPath, string outputPath, string password = null, ProgressAction onProgress = null)
        {
            if (!File.Exists(zipPath))
            {
                Debug.LogError($"Zip文件不存在：{zipPath}");
                return false;
            }
            return Unzip(File.OpenRead(zipPath), outputPath, password, onProgress);
        }

        /// <summary>
        /// 解压缩
        /// </summary>
        public static bool Unzip(byte[] zipData, string outputPath, string password = null, ProgressAction onProgress = null)
        {
            return Unzip(new MemoryStream(zipData), outputPath, password, onProgress);
        }

        /// <summary>
        /// 解压缩
        /// </summary>
        public static bool Unzip(Stream inputStream, string outputPath, string password = null, ProgressAction onProgress = null)
        {
            if (!Directory.Exists(outputPath)) Directory.CreateDirectory(outputPath);
            ZipEntry entry = null;
            Encoding encoding = Define.IsWebGL && !Application.isEditor ? Encoding.UTF8 : Encoding.GetEncoding("gbk");
            ZipConstants.DefaultCodePage = encoding.CodePage;
            using (ZipInputStream zipInputStream = new ZipInputStream(inputStream))
            {
                if (!string.IsNullOrEmpty(password))
                {
                    zipInputStream.Password = password;
                }

                int total = 0;
                int done = 0;
                if (onProgress != null)
                {
                    while (null != (entry = zipInputStream.GetNextEntry()))
                    {
                        total++;
                    }
                }
                while (null != (entry = zipInputStream.GetNextEntry()))
                {
                    done++;
                    if (onProgress != null && total > 0)
                    {
                        onProgress.Invoke(done / (float)total);
                    }

                    if (null == entry || string.IsNullOrEmpty(entry.Name)) continue;
                    string filePathName = System.IO.Path.Combine(outputPath, entry.Name);
                    string suffix = ".tmp";
                    if (entry.IsDirectory)
                    {
                        Directory.CreateDirectory(filePathName);
                        continue;
                    }
                    try
                    {
                        string filePathNameTmp = filePathName + suffix;
                        using (FileStream fileStream = File.Create(filePathNameTmp))
                        {
                            byte[] bytes = new byte[1024];
                            while (true)
                            {
                                int count = zipInputStream.Read(bytes, 0, bytes.Length);
                                if (count > 0)
                                {
                                    fileStream.Write(bytes, 0, count);
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                        if (File.Exists(filePathName)) File.Delete(filePathName);
                        File.Move(filePathNameTmp, filePathName);
                    }
                    catch (System.Exception _e)
                    {
                        Debug.LogError($"加压失败：{_e}");
                        return false;
                    }
                }
            }
            return true;
        }
    }
}
